package cn.kgc.service.impl;

import cn.kgc.base.vo.SecKillSessionAndSecKillSkuVO;

import cn.kgc.base.vo.SecKillSkuVo;
import cn.kgc.base.vo.SeckillSessionVO;
import cn.kgc.client.SmsFeignClient;
import cn.kgc.commons.util.RedisUtil;
import cn.kgc.commons.vo.Result;
import cn.kgc.constant.SeckillConstant;
import cn.kgc.service.SeckillService;

import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;


import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: 石浩杰
 * @date: 2023-01-07 14:29
 */
@Service("seckillService")
public class SeckillServiceImpl implements SeckillService {

    @Resource
    private SmsFeignClient smsFeignClient;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private RedissonClient redissonClient;

    @Override
    public String secKill(String randomCode, int seckillNum) {
        return null;
    }

    @Override
    public List<SecKillSessionAndSecKillSkuVO> getSkillSessionAndSku() {
       List<SecKillSessionAndSecKillSkuVO>result=new ArrayList<>();
       //获得今天的所有场次ID
        Result<List<SeckillSessionVO>> sessionResult = smsFeignClient.getSecSessions();
        if (sessionResult.getData()==null){
           return result;
        }
        List<SeckillSessionVO>longList=sessionResult.getData();

        result= longList.stream().map(seckillSessionVO -> {
            SecKillSessionAndSecKillSkuVO vo=new SecKillSessionAndSecKillSkuVO();
            //再根据场次ID获得场次中对应的商品的随机码
            List<String> randomCodeList =
                    (List<String>) redisUtil.get(SeckillConstant.SECKILL_SESSIONS_CACHE_PREFIX + seckillSessionVO.getId());
            List<SecKillSkuVo>secKillSkuVos=new ArrayList<>();
            //遍历随机码获得 商品信息
            for (String randomCode : randomCodeList) {
                String seckillSkuKey=SeckillConstant.SECKILL_SKU_CACHE_PREFIX+randomCode;
                SecKillSkuVo secKillSkuVo = (SecKillSkuVo) redisUtil.get(seckillSkuKey);
                secKillSkuVos.add(secKillSkuVo);
            }
            vo.setSessionId(seckillSessionVO.getId());
            vo.setSessionName(seckillSessionVO.getName());
            vo.setSessionStartTime(seckillSessionVO.getStartTime());
            vo.setSessionEndTime(seckillSessionVO.getEndTime());
            vo.setSecKillSkuVoList(secKillSkuVos);
            return vo;

        }).collect(Collectors.toList());
        //再根据随机码获得商品的信息
        return result;
    }

    @Override
    public boolean secKillSkuUp() {
        Result<List<SecKillSessionAndSecKillSkuVO>> result= smsFeignClient.getSecSessionAndSecSku();
        if (result.getData()==null){
            return false;
        }
        //key:场次id value:秒杀商品的id的集合
        //key:商品随机码 value:商品的信息
        for (SecKillSessionAndSecKillSkuVO datum : result.getData()) {
            long sessionId=datum.getSessionId();
            List<SecKillSkuVo> secKillSkuVos=datum.getSecKillSkuVoList();
            List<String> randomCodeList=new ArrayList<>();
            for (SecKillSkuVo secKillSkuVo : secKillSkuVos) {
                String randomCode=secKillSkuVo.getSkuRandomCode();
                //场次对应的随机码
                randomCodeList.add(randomCode);
                String seckillSkuCacheKey=SeckillConstant.SECKILL_SKU_CACHE_PREFIX+
                        randomCode;
                secKillSkuVo.setSessionStartTime(datum.getSessionStartTime());
                secKillSkuVo.setSessionEndTime(datum.getSessionEndTime());

                redisUtil.set(seckillSkuCacheKey,secKillSkuVo,SeckillConstant.SECKILL_SCK_LIVE_TIME, TimeUnit.HOURS);
                //秒杀商品上架的信号量
                String seckillSkuSemaphoreKey=SeckillConstant.SECKILL_SKU_SEMAPHORE+randomCode;
                //信号量
                RSemaphore rSemaphore=redissonClient.getSemaphore(seckillSkuSemaphoreKey);
                //初始化信号量
                rSemaphore.trySetPermits(secKillSkuVo.getSecKillCount());

            }
            //保存场次的id以及 场次对应的秒杀商品的随机码的集合
            String seckillSessionCacheKey= SeckillConstant.SECKILL_SESSIONS_CACHE_PREFIX +sessionId;
            redisUtil.set(seckillSessionCacheKey,randomCodeList,SeckillConstant.SECKILL_SCK_LIVE_TIME, TimeUnit.HOURS);
        }
        return true;
    }
}
